package com.ruoyi.web.controller.tool;

import com.ruoyi.system.mapper.DataMapper;
import io.swagger.annotations.Api;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Api("数据调取")
@RestController
@RequestMapping("/data")
public class DataController {

    final static Logger logger = LoggerFactory.getLogger(DataController.class);

    @Autowired
    DataMapper dataMapper;

    /**
     数据检索接口
     oper=操作，s=select，u=update，0-2=limit 0,2
     params支持表达式，并且过滤了sql注入
     把表达式放在value的前面，支持 %,>,<,>=,<=,=

     request({
     url: '/data/backend/s/test/0-2',
     headers: {
     isToken: true
     },
     // method: 'post',
     params: {'name':"'李--%",'age':'>=10'}   //支持防sql注入！
     }
     */
    @RequestMapping("/backend/{oper}/{table}/{limit}")
    public List<Map<String,Object>> backend(@PathVariable("oper") String oper,@PathVariable("table") String table,@PathVariable("limit") String limit, @RequestParam Map<String, String> allParams){
        String sql = parseParam(replaceInject(oper),replaceInject(table),replaceInjectMap(allParams),limit);
        logger.info(sql);
        return dataMapper.select(sql);
    }


    private String parseParam(String oper,String table,Map<String, String> allParams,String limit){
        String sql = "";
        //不允许对系统表泛查询
        if (table.startsWith("sys_")){
            return "";
        }
        switch (oper){
            case("s"):
                sql += "select * from " + table + " where 1=1 ";
                sql += concatWhere(allParams);
                if (!"-".equals(limit)){
                    sql += " limit "+limit.replace("-",",");
                }
                break;
            case("u"):
                sql += "update "+table;
                sql += concatSet(allParams);
                break;
        }
        System.out.println("===>data execute: "+sql);
        return sql;
    }

    //防止sql注入
    private String replaceInject(String param){
        return param.replaceAll("'","").replaceAll("--","");
    }

    private Map<String, String> replaceInjectMap(Map<String, String> allParams){
        final Map<String, String> map = new HashMap<String, String>();
        allParams.entrySet().forEach(e ->{
            map.put(replaceInject(e.getKey()),replaceInject(e.getValue()));
        });
        return map;
    }

    private String concatWhere(Map<String, String> allParams){
        final StringBuilder sql = new StringBuilder();
        allParams.entrySet().forEach(e ->{
            if (e.getValue().startsWith("=") ||e.getValue().startsWith(">") || e.getValue().startsWith("<")
                    || e.getValue().startsWith(">=") || e.getValue().startsWith("<=")) {
                sql.append(" and "+e.getKey()+e.getValue());
            } else if (e.getValue().contains("-")) {
                String[] v = e.getValue().split("-");
                sql.append(" and "+e.getKey()+" between " + v[0] + " and "+ v[1]);
            } else{
                sql.append(" and " +e.getKey()+" like '"+e.getValue()+"' ");
            }
        });
        return sql.toString();
    }

    private String concatSet(Map<String, String> allParams){
        final StringBuilder sql = new StringBuilder();
        allParams.entrySet().forEach(e ->{
            sql.append(" set " +e.getKey() + " = '"+e.getValue()+"' ");
        });
        sql.append(" where id = '"+allParams.get("id")+"' ");
        return sql.toString();
    }
}
